Repository navigation
Conversation
…a channel Add conversation.ui.Conversation, a host-owned scope for a page's own ui.Message rows and ui.Composer in one channel. It reuses the existing non-visiting ConversationChannel host mode, so rows get native edit, confirmed delete with recovery and retry, a per-scope edit target and host media review, while mounting never marks read, follows or holds the channel roster. Fixes NEXUS-4193 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kyle Zemek <kylez@squareup.com>
… consumer Observe the profile reservation an open channel makes, exercise ui.Conversation and its interactions in the packed author consumer fixture, and name the instance rather than the scope prop in the docs. Refs NEXUS-4193 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kyle Zemek <kylez@squareup.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Kyle Zemek <kylez@squareup.com>
kazemek21
marked this pull request as ready for review
November 4, 2026 23:39
joahg
approved these changes
Nov 5, 2026
joahg
left a comment
Member
There was a problem hiding this comment.
🤖 Read the EmbeddedConversation/HostedChannel refactor and the no-visit scope. EmbeddedThread behavior is unchanged, and the new tests assert enterChannel, follow and mark-read are never called.
cheng-block
added a commit
to cheng-block/buzz-app
that referenced
this pull request
Nov 5, 2026
…ettings-shift-esc * upstream/main: (40 commits) feat(conversation): let plugin rows manage messages without visiting a channel (block#2512) feat(github): make side-panel link opening optional (block#2629) feat(messages): show a blurred thumbnail until an image loads (block#2556) fix(relay): give large roster and read-state reads a 30s deadline (block#2627) fix(user-status): show a status emoji's :name: on hover where the full status shows (block#2384) fix(inbox): keep the list's place when returning in the same session (block#2134) fix(messages): pass verified labels to the forward recipient picker (block#2633) feat(messages): forward a message to a person (block#2167) docs(agents): design relay-facing paths for the whole fleet at once (block#2620) Route debug sessions through the credential helper (block#2541) perf(search): skip no-op slow-search resets on each keystroke (block#2605) perf(agents): dedupe channel members only for dm connection setup (block#2603) perf(search): keep the search tab row across palette keystrokes (block#2588) perf(sidebar): skip the hidden actions menu in solo and team headers (block#2582) perf(search): rank each palette name once per render (block#2606) perf(sidebar): skip re-rendering unchanged animated channel rows (block#2572) feat(settings): follow the system clock and let people hide message times (block#2440) feat(plugins): repository access rules for Git imports (block#2484) feat(desktop): add Settings to the macOS app menu (block#2594) Preserve and renew external app approval (block#2464) ... Signed-off-by: Cheng Peng <cheng@block.xyz> Co-authored-by: Cursor <cursoragent@cursor.com>
johnmatthewtennant
added a commit
that referenced
this pull request
Nov 5, 2026
…thumbnails * origin/main: (120 commits) feat(conversation): let plugin rows manage messages without visiting a channel (#2512) feat(github): make side-panel link opening optional (#2629) feat(messages): show a blurred thumbnail until an image loads (#2556) fix(relay): give large roster and read-state reads a 30s deadline (#2627) fix(user-status): show a status emoji's :name: on hover where the full status shows (#2384) fix(inbox): keep the list's place when returning in the same session (#2134) fix(messages): pass verified labels to the forward recipient picker (#2633) feat(messages): forward a message to a person (#2167) docs(agents): design relay-facing paths for the whole fleet at once (#2620) Route debug sessions through the credential helper (#2541) perf(search): skip no-op slow-search resets on each keystroke (#2605) perf(agents): dedupe channel members only for dm connection setup (#2603) perf(search): keep the search tab row across palette keystrokes (#2588) perf(sidebar): skip the hidden actions menu in solo and team headers (#2582) perf(search): rank each palette name once per render (#2606) perf(sidebar): skip re-rendering unchanged animated channel rows (#2572) feat(settings): follow the system clock and let people hide message times (#2440) feat(plugins): repository access rules for Git imports (#2484) feat(desktop): add Settings to the macOS app menu (#2594) Preserve and renew external app approval (#2464) ... Signed-off-by: John Tennant <jtennant@squareup.com> # Conflicts: # src-tauri/src/relay.rs
agude-sq
added a commit
to agude-sq/buzz-app
that referenced
this pull request
Nov 5, 2026
* origin/main: (28 commits) fix(mcp): accept create scopes in durable approvals (block#2650) feat(bestie): Bestie tab and Remembers you for a hosted Bestie (block#2478) fix(relay): p-tag a one-to-one DM's agent partner on new messages (block#2475) fix(agents): show each message author's username and display name (block#2628) fix(agents): preserve visible edits in conversation history (block#2355) fix(canvas): keep todo edits from approving unrelated instructions (block#2350) fix(messages): keep messages in their canonical channel (block#2349) NEXUS-4165: Add Thinking to agent creation (block#2409) feat(plugins): let a plugin paint a backdrop behind the shell (block#2437) feat(search): lead empty quick open with unread conversations (block#2634) NEXUS-4170: Allow external apps to create private Solo chats (block#2411) fix(acp): count grouped thinking levels when checking a synced level (block#2640) feat(conversation): let plugin rows manage messages without visiting a channel (block#2512) feat(github): make side-panel link opening optional (block#2629) feat(messages): show a blurred thumbnail until an image loads (block#2556) fix(relay): give large roster and read-state reads a 30s deadline (block#2627) fix(user-status): show a status emoji's :name: on hover where the full status shows (block#2384) fix(inbox): keep the list's place when returning in the same session (block#2134) fix(messages): pass verified labels to the forward recipient picker (block#2633) feat(messages): forward a message to a person (block#2167) ... # Conflicts: # tests/browser/settings.spec.mjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
Adds
conversation.ui.Conversation, a public host-owned scope that lets a plugin's ownui.Messagerows andui.Composerfor one channel get native Edit, confirmed Delete with recovery and retry, and host media review. Mounting it never marks anything read, follows a thread or enters the channel visit. Cross-channel overview cards need this; today a bareui.Messagerow has neither Edit nor Delete, andui.Threadalways visits.Fixes NEXUS-4193
How it works
ui.Conversation({ session, scope, channelId, channelName?, threadId?, children(interactions) })renders the existingConversationChannelin its host-dialog, non-visiting mode (hostplusactive={false}). Inbox Drafts already uses this mode internally. Inside it:MessageManagementsupplies the row menu's Edit/Delete under the existing permission checks, the delete confirmation and the failed/unconfirmed recovery notice.MessageEditScopemakes Edit target theui.Composerin the same scope. A scope without a composer offers no Edit, as in other previews.ConversationHostowns media review and panel overlays, focus return, and the existing stale-session guard (nothing opens once the relay snapshot is no longer this ready session).childrenreceives the host'sonOpenLink,canOpenLinkandonOpenMediaReviewto pass to the rows.EmbeddedThreadand the new scope now share oneHostedChannelwrapper, soui.Threadbehavior is unchanged. No changes toMessageManagement,ConversationHost,MessageComposerorcontracts.ts.Evidence
src/features/conversation/EmbeddedConversation.test.tsxmounts two fictional channel cards (real relay session, realui.Messagerows andui.ComposerfromConversationService; onlyMediaReviewVieweris reduced, since it has its own suites). It covers:enterChannel,leaveChannel,follow,markMessageRead,markChannelReador the roster'sprofiles.reserve, and publish nothingFail-then-pass: with
active={false}removed from the scope, all 4 tests fail (enterChannelandprofiles.reserveare called). The scope restored, all pass.The packed
@buzz/authorconsumer fixture (tests/fixtures/conversation-consumer) now renders its rows and composer insideui.Conversationand passesinteractions.onOpenLinkto its rows. So the generated declarations must export the new component and itschildren(interactions)type, and the existingconversation.spec.mjsjourney mounts it in the real app. The fixture type-checks against freshly built declarations. As a negative control, a misspelled interactions field failstsc.Run on a Linux Blox box on base
a34ba4f(the local host-build guard refused under load):vitest run src/features/conversation src/features/messages/MessageManagement.test.tsx src/bundled/inbox/DraftsView.test.tsx: 19 files, 221 tests passedtsc --noEmitandbiome check --error-on-warningson the touched files: cleanpnpm author:build, packed and installed into a copy of the consumer fixture, thenpnpm build(tsc): cleanNo browser journeys were added or removed. The existing consumer journey now mounts the scope; it runs only in hosted CI, not locally. Focus, overlay and native-edit geometry are unchanged existing
ConversationHost/composer behavior that existing suites already cover.Limits and coordination
ui.Conversations for the same channel each show that channel's recovery notice, because recovery is per channel. The docs say to render one per channel or card.service.tsx), NEXUS-4029: Add task source references and primary controls #1889, NEXUS-4022: Create durable task chats in New Chat #2306 or NEXUS-4022: Preserve Nexus metadata in existing composer tokens #2303 (contracts.ts), NEXUS-4082: Keep the new-message boundary stable during a visit #2083 (MessageManagement.tsx) or feat(messages): forward a message to a person #2167 (ConversationHost.tsx). This PR does not editcontracts.ts,MessageManagement.tsxorConversationHost.tsx.Initiative context
Buzz Threads status
🤖 Generated with Claude Code